// Created by carolsail

import { ENUM_AUDIO_CLIP, ENUM_GAME_MODE } from "../Enum";
import { StaticInstance } from "../StaticInstance";
import AudioManager from "../manager/AudioManager";
import DataManager, { POINT_BORN, POINT_LINE, POINT_ROUND, POINT_START } from "../manager/DataManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Chess extends cc.Component {

    @property([cc.SpriteFrame])
    bodies: cc.SpriteFrame[] = [];

    anim: cc.Animation = null
    tail: cc.ParticleSystem = null
    // 颜色
    type: number = 0
    // 4个同色棋子索引
    index: number = 0
    // 位置
    pos: number = -2

    onLoad() {
        this.node.on('touchstart', this.onTouch, this)
        this.anim = this.node.getChildByName('Body').getComponent(cc.Animation)
        this.tail = this.node.getChildByName('Tail').getComponent(cc.ParticleSystem)
    }

    protected onDestroy(): void {
        this.node.off('touchstart', this.onTouch, this)
    }

    init(type: number, index: number, pos: number = -2) {
        this.type = type
        this.index = index
        this.pos = pos
        this.rendor()
    }

    rendor() {
        const body = this.node.getChildByName('Body')
        body.getComponent(cc.Sprite).spriteFrame = this.bodies[this.type]
        let px: number = 0
        let py: number = 0
        let pr: number = 0
        if (this.pos == -2) {
            // 出生点
            const { x, y, rotation } = POINT_BORN[this.type][this.index]
            px = x
            py = y
            pr = rotation
        }
        if (this.pos == -1) {
            // 起飞点
            const { x, y, rotation } = POINT_START[this.type]
            px = x
            py = y
            pr = rotation
        }
        if (this.pos >= 0 && this.pos <= 49) {
            // 环形跑道上
            const { x, y, rotation } = POINT_ROUND[this.type][this.pos]
            px = x
            py = y
            pr = rotation
        }
        if (this.pos >= 50 && this.pos < 55) {
            // 直线跑道上
            const { x, y, rotation } = POINT_LINE[this.type][this.pos - 50]
            px = x
            py = y
            pr = rotation
        }
        if (this.pos == 55) {
            this.node.getChildByName('Body').opacity = 0
            this.node.getChildByName('Tail').active = false
            this.node.getChildByName('Star').opacity = 255
            const { x, y } = POINT_BORN[this.type][this.index]
            px = x
            py = y
            pr = 0
        }
        this.node.setPosition(px, py)
        this.node.angle = pr
    }

    setActive(status: boolean = true) {
        if (status) {
            this.anim.play('scale')
        } else {
            this.anim.stop('scale')
        }
    }

    setEndpoint() {
        // 抵达终点，转化为星星
        this.node.getChildByName('Body').opacity = 0
        this.node.getChildByName('Tail').active = false
        this.node.getChildByName('Star').opacity = 255
        const { x, y } = POINT_BORN[this.type][this.index]
        AudioManager.instance.playSound(ENUM_AUDIO_CLIP.ENDPOINT)
        const act = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, 0))
        cc.tween(this.node).then(act).start()
    }

    setBorn() {
        // 强制回出生点
        const { x, y, rotation } = POINT_BORN[this.type][this.index]
        AudioManager.instance.playSound(ENUM_AUDIO_CLIP.BOMB)
        StaticInstance.effectManager.playInParent('Explode', this.node)
        const act = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -rotation))
        cc.tween(this.node).then(act).start()
        this.pos = -2
        DataManager.instance.posData[this.type][this.index] = -2
    }

    onTouch() {
        if (!this.anim.getAnimationState('scale').isPlaying) return
        if (DataManager.instance.mode == ENUM_GAME_MODE.SINGLE) {
            StaticInstance.gameManager.onPlaneTouch(this)
        } else {
            if (DataManager.instance.round == DataManager.instance.role) {
                const params = {
                    type: 'msg_plane_touch',
                    room: DataManager.instance.room,
                    content: {
                        planeType: this.type,
                        planeIndex: this.index
                    }
                }
                DataManager.instance.wsClient.callApi('GameSync', params)
            }
        }
    }

    /**
     * 环绕跑道50格
     * 位置>49则进入直线跑道（初始位置0）
     */
    move(step: number) {
        let actions = []
        let actionTime = 0
        let jumpType = 0
        if (step > 0) {
            AudioManager.instance.playSound(ENUM_AUDIO_CLIP.FLY)
            if (this.isBorn()) {
                // 准备起飞
                const { x, y, rotation } = POINT_START[this.type]
                const action = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -rotation))
                actions.push(action)
                actionTime += 0.3
                this.pos = -1
                DataManager.instance.posData[this.type][this.index] = -1
                // 碰撞检测
                jumpType = 3
                const cb = cc.callFunc(() => { StaticInstance.gameManager.onPlaneCheck(this, jumpType) })
                actions.push(cb)
            } else {
                // 环绕跑道
                const roundIndexArr = []
                let tempIndex = this.pos
                for (let i = 0; i < step; i++) {
                    tempIndex += 1
                    if (tempIndex <= 49) {
                        roundIndexArr.push(tempIndex)
                        this.pos = tempIndex
                        DataManager.instance.posData[this.type][this.index] = tempIndex
                    }
                }
                // 直线跑道
                const lineIndexArr = []
                if (tempIndex > 49) {
                    let lineStep = tempIndex - this.pos
                    let ahead = true
                    while (lineStep > 0) {
                        if (ahead) {
                            // 前进
                            const index = this.pos - 49
                            lineIndexArr.push(index)
                            this.pos += 1
                            DataManager.instance.posData[this.type][this.index] += 1
                            if (this.pos >= 55) ahead = false
                        } else {
                            // 倒退
                            this.pos -= 1
                            DataManager.instance.posData[this.type][this.index] -= 1
                            const index = this.pos - 50
                            lineIndexArr.push(index)
                        }
                        lineStep--
                    }
                    ahead = true
                }
                // console.log(`飞机：${this.type}`, `塞子：${step}`, `位置：${this.pos}`)
                // 缓动入栈
                for (let i = 0; i < roundIndexArr.length; i++) {
                    const { x, y, rotation } = POINT_ROUND[this.type][roundIndexArr[i]]
                    const action = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -rotation))
                    actions.push(action)
                    actionTime += 0.3
                    // 同色跳跃
                    if (i == roundIndexArr.length - 1 && this.pos <= 49) {
                        const point = POINT_ROUND[this.type][this.pos]
                        if (point.jumpto) {
                            const cb_audio = cc.callFunc(() => { AudioManager.instance.playSound(ENUM_AUDIO_CLIP.FLY) })
                            actions.push(cb_audio)
                            // console.log(`飞机${this.type}`, `塞子${step}`, `跳跃${point.jumpto}`)
                            const { x, y, rotation } = POINT_ROUND[this.type][point.jumpto]
                            jumpType = 1
                            if (this.pos == 17) {
                                jumpType = 2
                                const r1 = (-90 + this.type * -90) % 360
                                const act1 = cc.rotateTo(0.1, -r1)
                                const act2 = cc.spawn(cc.moveTo(0.5, x, y), cc.rotateTo(0.5, -rotation))
                                const act = cc.sequence(act1, act2)
                                actions.push(act)
                                actionTime += 0.6
                            } else {
                                if (this.pos == 45) {
                                    const r1 = rotation + 90
                                    const act1 = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -r1))
                                    const act2 = cc.rotateTo(0.1, -rotation)
                                    const act = cc.sequence(act1, act2)
                                    actions.push(act)
                                    actionTime += 0.4
                                } else {
                                    const action = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -rotation))
                                    actions.push(action)
                                    actionTime += 0.3
                                }
                            }

                            this.pos = point.jumpto
                            DataManager.instance.posData[this.type][this.index] = point.jumpto
                            // 碰撞检测
                            const cb = cc.callFunc(() => { StaticInstance.gameManager.onPlaneCheck(this, jumpType) })
                            actions.push(cb)
                        } else {
                            // 碰撞检测
                            const cb = cc.callFunc(() => { StaticInstance.gameManager.onPlaneCheck(this, jumpType) })
                            actions.push(cb)
                        }
                    }
                }
                for (let i = 0; i < lineIndexArr.length; i++) {
                    const { x, y, rotation } = POINT_LINE[this.type][lineIndexArr[i]]
                    const action = cc.spawn(cc.moveTo(0.3, x, y), cc.rotateTo(0.3, -rotation))
                    actions.push(action)
                    actionTime += 0.3
                    // 碰撞检测
                    if (i == lineIndexArr.length - 1) {
                        jumpType = 3
                        const cb = cc.callFunc(() => { StaticInstance.gameManager.onPlaneCheck(this, jumpType) })
                        actions.push(cb)
                    }
                }
            }
            // 开始移动
            if (actions.length) {
                let act = actions[0]
                if (actions.length > 1) {
                    act = cc.sequence(actions)
                }
                // tail particle
                if (this.pos >= -1) {
                    this.tail.enabled = true
                    this.tail.resetSystem()
                }
                cc.tween(this.node).then(act).call(() => {
                    this.tail.enabled = false
                }).start()
            }
        } else {
            actionTime = 0.3
        }
        // 结束回合
        StaticInstance.gameManager.onPlaneEnd(this, actionTime)
    }

    isBorn() {
        return this.pos == -2
    }

    isReady() {
        return this.pos == -1
    }

    isRound() {
        return this.pos >= 0 && this.pos <= 49
    }

    isLine() {
        return this.pos >= 50 && this.pos < 55
    }

    isEndpoint() {
        return this.pos == 55
    }

    isUnSafeInLine() {
        return this.pos == 52
    }

    // 统一坐标
    getRoundPosBaseRed(pos: number = null) {
        // 一圈52格, 相邻间隔14
        if (pos) return (pos + 13 * this.type) % 52
        return (this.pos + 13 * this.type) % 52
    }
}
